package com.enlorenz.common.excel;

import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import com.enlorenz.common.util.DataDetUtils;

/**
 * 抽象的数据导出者
 * @author Karma
 */
public abstract class AbstractDataExporter<T> implements IDataExporter<T>{
	public static final short DEFAULT_COL_WIDTH=-1;
	//属性列表
	protected List<String> propList;
	//元素遍历器
	protected IDataElementIterator<T> elementIterator;
	//数据列表
	private List<T> dataList;
	//允许的列表
	private String [] permitPropList;
	//不允许的列表
	private String [] ignorePropList;
	//是否展示表头
	protected boolean showTitle=true;
	
	private Integer rouCount=0;
	/**
	 * 设置数据的class
	 * @param dataClass 数据class
	 */
	public AbstractDataExporter(Class<T> dataClass){
		elementIterator=new TransPropDataElementIterator<T>(dataClass);
	}
	
	@Override
	public void setElementIterator(IDataElementIterator<T> elementIterator) {
		this.elementIterator=elementIterator;
	}

	@Override
	public void setDataList(List<T> dataList) {
		this.dataList=dataList;
	}
	
	public AbstractDataExporter(){}
	
	/**
	 * 设置禁用属性列表
	 * @param ignoreList 禁用属性列表
	 */
	public void setIgnorePropList(String [] ignorePropList){
		this.ignorePropList=ignorePropList;
	}


	@Override
	public void setPermitPropList(String[] permitPropList) {
		this.permitPropList=permitPropList;
	}


	
	/**
	 * 在导出之前做的事情
	 * @param outputStream
	 */
	protected void beforeExport(OutputStream outputStream){
		
	}
	
	/**
	 * 在导出之后做的事情
	 * @param outputStream
	 */
	protected void afterExport(OutputStream outputStream){
		
	}
	
	@Override
	public void export(OutputStream outputStream) {
		if(!DataDetUtils.isArrEmpty(permitPropList)){
			propList=new ArrayList<String>(permitPropList.length);
			//有注释的列
			List<String> hasList=elementIterator.getPropList();
			for(String s:permitPropList){
				if(hasList.contains(s)){
					propList.add(s);
				}
			}
		}else{
			propList=elementIterator.getPropList();
		}
		
		
		if(!DataDetUtils.isArrEmpty(ignorePropList)){
			for(String s:ignorePropList){
				propList.remove(s);
			}
		}
		
		//在导出之前做的事情
		beforeExport(outputStream);
		
		if(isShowTableTitle()){
			if(0 != propList.size()){
				int curRow=generateRowCount();
				initPropHead(curRow);
				for(int i=0;i<propList.size();i++){
					String headKey=propList.get(i);
					DataHeadParam dataHeadParam=elementIterator.getHeadParam(headKey);
					doHeadValue(i,propList.size(),dataHeadParam);
				}
			}
		}
		
		if(!DataDetUtils.isCollectionEmpty(dataList)){
			for(int i=0;i<dataList.size();i++){
				T t=dataList.get(i);
				int curRow=generateRowCount();
				initRowData(curRow);
				for(int j=0;j<propList.size();j++){
					String s=propList.get(j);
					String dataValue=elementIterator.getDataValue(t, s);
					doDataValue(curRow,dataList.size(),j,propList.size(),dataValue);
				}
			}
		}
		//在导出之后做的事情
		afterExport(outputStream);
		//写出数据流
		writeOutputStream(outputStream);
	}
	
	protected boolean isShowTableTitle(){
		return showTitle;
	}
	
	public void setShowTableTitle(boolean showTitle){
		this.showTitle=showTitle;
	}
	
	/**
	 * 初始化表头
	 */
	protected void initPropHead(int curRow){
		
	}
	
	/**
	 * 初始化行数据
	 */
	protected void initRowData(int curRow){
		
	}
	
	protected Integer generateRowCount(){
		return rouCount++;
	}
	
	protected Integer getRowCount(){
		return rouCount;
	}
	
	/**
	 * 处理表头数据
	 * @param colIndex 当前列
	 * @param colSize 列总数
	 * @param dataHeadParam 值
	 */
	protected abstract void doHeadValue(int colIndex,int colSize,DataHeadParam dataHeadParam);
	
	/**
	 * 处理数据
	 * @param rowIndex 当前行
	 * @param rowSize 行总数
	 * @param colIndex 当前列
	 * @param colSize 列总数
	 * @param dataValue 值
	 */
	protected abstract void doDataValue(int rowIndex,int rowSize,int colIndex,int colSize,String dataValue);
	
	/**
	 * 写出数据流
	 * @param outputStream 输出流
	 */
	protected abstract void writeOutputStream(OutputStream outputStream);
}
